#define bmp180	0xee
#define AC1_reg_msb 0xAA
#define AC1_reg_lsb 0xAB
#define AC2_reg_msb 0xAC
#define AC2_reg_lsb 0xAD
#define AC3_reg_msb 0xAE
#define AC3_reg_lsb 0xAF
#define AC4_reg_msb 0xB0
#define AC4_reg_lsb 0xB1
#define AC5_reg_msb 0xB2
#define AC5_reg_lsb 0xB3
#define AC6_reg_msb 0xB4
#define AC6_reg_lsb 0xB5
#define B1_reg_msb 0xB6
#define B1_reg_lsb 0xB7
#define B2_reg_msb 0xB8
#define B2_reg_lsb 0xB9
#define MB_reg_msb 0xBA
#define MB_reg_lsb 0xBB
#define MC_reg_msb 0xBC
#define MC_reg_lsb 0xBD
#define MD_reg_msb 0xBE
#define MD_reg_lsb 0xBF

#define bmp180_out_msb_reg 0xf6
#define bmp180_out_lsb_reg 0xf7

#define oss 0

#include <math.h>


class es_Bmp180
{
private:
	public:
	
	CI2C* i2c;
	short AC1;
	short AC2;
	short AC3;
	u16 AC4;
	u16 AC5;
	u16 AC6;
	short B1;
	short	B2;
	short MB;
	short MC;
	short MD;

	long UT;
	long UP;

	long X1;
	long X2;
	long X3;
	long B5;
	long B6;
	long B3;
	unsigned long B4;
	unsigned long B7;
	long T;
	long P;
	double ati;
	


	void init(CI2C* bus){
		i2c = bus;
		Calibrate();
	};
	
	
	void Calibrate()
	{
	//		i2c->read16bit_reg(bmp180, AC1_reg_msb, &AC1);
		
			u8 temp;
			i2c->master_read_reg(bmp180, AC1_reg_msb, temp);
			AC1 = 0;
			AC1 |= temp<<8;
			i2c->master_read_reg(bmp180, AC1_reg_lsb, temp);
			AC1 |= temp;
		
			i2c->master_read_reg(bmp180, AC2_reg_msb, temp);
			AC2 = 0;
			AC2 |= temp<<8;
			i2c->master_read_reg(bmp180, AC2_reg_lsb, temp);
			AC2 |= temp;
		
			i2c->master_read_reg(bmp180, AC3_reg_msb, temp);
			AC3 = 0;
			AC3 |= temp<<8;
			i2c->master_read_reg(bmp180, AC3_reg_lsb, temp);
			AC3 |= temp;
		
			i2c->master_read_reg(bmp180, AC4_reg_msb, temp);
			AC4 = 0;
			AC4 |= temp<<8;
			i2c->master_read_reg(bmp180, AC4_reg_lsb, temp);
			AC4 |= temp;
			
			i2c->master_read_reg(bmp180, AC5_reg_msb, temp);
			AC5 = 0;
			AC5 |= temp<<8;
			i2c->master_read_reg(bmp180, AC5_reg_lsb, temp);
			AC5 |= temp;
			
			i2c->master_read_reg(bmp180, AC6_reg_msb, temp);
			AC6 = 0;
			AC6 |= temp<<8;
			i2c->master_read_reg(bmp180, AC6_reg_lsb, temp);
			AC6 |= temp;
			
			i2c->master_read_reg(bmp180, B1_reg_msb, temp);
			B1 = 0;
			B1 |= temp<<8;
			i2c->master_read_reg(bmp180, B1_reg_lsb, temp);
			B1 |= temp;
			
			i2c->master_read_reg(bmp180, B2_reg_msb, temp);
			B2 = 0;
			B2 |= temp<<8;
			i2c->master_read_reg(bmp180, B2_reg_lsb, temp);
			B2 |= temp;
			
			i2c->master_read_reg(bmp180, MB_reg_msb, temp);
			MB = 0;
			MB |= temp<<8;
			i2c->master_read_reg(bmp180, MB_reg_lsb, temp);
			MB |= temp;
			
			i2c->master_read_reg(bmp180, MC_reg_msb, temp);
			MC = 0;
			MC |= temp<<8;
			i2c->master_read_reg(bmp180, MC_reg_lsb, temp);
			MC |= temp;
			
			i2c->master_read_reg(bmp180, MD_reg_msb, temp);
			MD = 0;
			MD |= temp<<8;
			i2c->master_read_reg(bmp180, MD_reg_lsb, temp);
			MD |= temp;
	} 


	
	u32 readUncompensatedTemp()
	{
		u8 temp;
		i2c->master_write_reg(bmp180, 0xF4, 0x2E);
		//should wait 4.5ms here
		for(int i=0;i<0xfffff;i++);
		i2c->master_read_reg(bmp180, bmp180_out_msb_reg, temp);
		UT = 0;
		UT |= temp<<8;
		i2c->master_read_reg(bmp180, bmp180_out_lsb_reg, temp);
		UT |= temp;
	
		
		return UT;
	};
	
	
	u32 readUncompensatedAtt()
	{
		u8 temp;
		i2c->master_write_reg(bmp180, 0xF4, 0x34+oss);
		//should wait 4.5ms here
		for(int i=0;i<0xfffff;i++);
		i2c->master_read_reg(bmp180, bmp180_out_msb_reg, temp);
		UP = 0;  
		UP |= temp<<16;
		i2c->master_read_reg(bmp180, bmp180_out_lsb_reg, temp);
		UP |= temp<<8;
		i2c->master_read_reg(bmp180, bmp180_out_lsb_reg+1, temp);
		UP |= temp;
		
		UP = UP>>(8-oss);
		return UP;
	};
	
	float calc()
	{
		X1=(UT-AC6)*AC5/32768;;
		X2=MC*2048/(X1+MD);
		B5=X1+X2;
		T = (B5+8)/16;
		
		B6=B5-4000;
		X1=(B2*(B6*B6/4096))/2048;
		X2=AC2*B6/2048;
		X3=X1+X2;
		B3=(((AC1*4+X3)<<oss)+2)/4;
		X1=AC3*B6/8192;
		X2=(B1*(B6*B6/4096))/65536;
		X3=((X1+X2)+2)/4;
		B4=AC4*(unsigned long)(X3+32768)/32768;
		B7=((unsigned long)UP-B3)*(50000>>oss);
		if(B7<0x80000000)
			P=(B7*2)/B4;
		else
			P=(B7/B4)*2;
		X1=(P/256)*(P/256);
		X1=(X1*3038)/65536;
		X2=(-7357*P)/65536;
		P=P+(X1+X2+3791)/16;
		
		ati = 44330*((double)1-pow(((double)(P/100)/1013.25),(double)1/(double)5.255));
		
		return ati;
	}
};
